﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using Babylon.Toolbox;
using XnaTools;
using Microsoft.Xna.Framework;
using SStuff.XnaInterop;
using System.IO;
using Microsoft.Xna.Framework.Silverlight;
using Microsoft.Xna.Framework.Graphics;
using Babylon.Primitives;

namespace LizardSample
{
    public class Scene : BaseScene
    {

        OrbitCamera _camera;

        private Color _lightColor = new Color(1.0f, 1.0f,1.0f,1.0f);

        public Color LightColor
        {
            get { return _lightColor; }
            set { _lightColor = value; }
        }

        private Color _ambientLightColor = new Color(.2f, .2f, .2f, 1.0f);

        public Color AmbientLightColor
        {
            get { return _ambientLightColor; }
            set { _ambientLightColor = value; }
        }

        private float _shininess = 1.0f;

        public float Shininess
        {
            get { return _shininess; }
            set { _shininess = value; }
        }

        private float _specularPower = 12.0f;

        public float SpecularPower
        {
            get { return _specularPower; }
            set { _specularPower = value; }
        }


        ColoredEllipse _lightEllipse;

        public Scene(DrawingSurface drawingSurface, FrameworkElement inputSurface)
            : base(drawingSurface, inputSurface)
        {
            _camera = new OrbitCamera();
            _camera.FarPlane = 100000;
            _camera.NearPlane = 0.1f;
            _camera.Radius = 1500;
            _camera.AttachTo(inputSurface);
            _lightEllipse = new ColoredEllipse(10, 10, 40, new Color(0,0,0,1.0f));
        }


        private InteropModel _lizard;
        private Model _babyLizard;


        Matrix[] _absoluteTransforms;
        protected override void OnLoaded(object sender, RoutedEventArgs e)
        {
            using(var fs = Application.GetResourceStream(new Uri("Models/lizard.bin", UriKind.Relative)).Stream)
            using (var reader = new BinaryReader(fs))
            {
                _lizard = InteropModel.FromBinaryReader(reader);
            }

            var gd = GraphicsDeviceManager.Current.GraphicsDevice;

            _lizard.Prepare(gd);
            _babyLizard = _lizard.ToBabylonModel(gd, (m, p) => {
                var effect = new BasicEffect(gd);
                effect.SceneAmbientColor = _ambientLightColor;
                effect.AmbientColor = new Color(0.3f,0.3f,0.3f,1);
                effect.SpecularPower = _specularPower;
                effect.SpecularColor = new Color(1,1,1,_shininess);
                effect.DiffuseTexture = p.IndexedTextureUsages["Texture"].SL5Texture;
                effect.BumpTexture = p.IndexedTextureUsages["NormalMap"].SL5Texture;
                effect.InvertBinormal = true;
                return effect;
            });

            _lightEllipse.Device = gd;
            _lightEllipse.LoadContent();
            VertexColorEffect lightEffect = new VertexColorEffect(gd);
            _lightEllipse.Effect = lightEffect;
            lightEffect.EmissiveColor = new Color(1.0f, 1.0f, 0.8f, 1.0f);
           
            _absoluteTransforms = new Matrix[_babyLizard.Bones.Count];
            _babyLizard.CopyAbsoluteBonesTo(_absoluteTransforms);


        }

        float _width, _height;
        protected override void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            _width = (float)e.NewSize.Width;
            _height = (float)e.NewSize.Height;
            _camera.AspectRatio = _width/_height;
        }

        protected override void OnDraw(object sender, DrawEventArgs e)
        {
            var gd = e.GraphicsDevice;
            gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(50, 100, 200, 255), 1, 0);

            float lightRotation = (float)e.TotalTime.TotalSeconds * 0.5f;

            _lightEllipse.Device = gd;
            var lightEffect = _lightEllipse.Effect as VertexColorEffect;
            lightEffect.Device = gd;


            Matrix lightRotationMatrix = Matrix.CreateRotationY(lightRotation);
            Vector3 lightPosition = new Vector3(800, 900, 0);
            lightPosition = Vector3.Transform(lightPosition, lightRotationMatrix);

            lightEffect.World = Matrix.CreateTranslation(800,900,0) * lightRotationMatrix;
            lightEffect.View = _camera.View;
            lightEffect.Projection = _camera.Projection;
            _lightEllipse.Draw();

            foreach (var modelMesh in _babyLizard.Meshes){
                foreach (var effect in modelMesh.Effects){
                    effect.Device = gd;
                    var be = effect as BasicEffect;
                    be.LightPosition = lightPosition;
                    be.View = _camera.View;
                    be.Projection = _camera.Projection;
                    be.CameraPosition = _camera.Position;
                    be.World = _absoluteTransforms[modelMesh.BoneIndex];
                }
            }
            _babyLizard.Device = gd;
            
            _babyLizard.Draw();
            _camera.ApplyInertia();
            //for (int i = 0; i < _lizard.Meshes.Length; i++)
            //{
            //    var mesh = _lizard.Meshes[i];
            //    _paramWorld.SetValue(_absoluteTransforms[mesh.BoneIndex]);
            //    _paramWorld.Apply();
            //    for (int j = 0; j < mesh.Parts.Length; j++)
            //    {
            //        var part = mesh.Parts[j];
            //        gd.Textures[_paramDiffuseTextureSampler.PixelShaderRegisterIndex] = part.IndexedTextureUsages["Texture"].SL5Texture;
            //        gd.Textures[_paramNormalMapSampler.PixelShaderRegisterIndex] = part.IndexedTextureUsages["NormalMap"].SL5Texture;
            //        part.Draw(gd);
            //    }
            //}

            e.InvalidateSurface();

        }

    }
}
